package cz.cvut.fit.mi_paa.sat.strategy;

import cz.cvut.fit.mi_paa.abs.Context;
import cz.cvut.fit.mi_paa.abs.Strategy;
import cz.cvut.fit.mi_paa.sat.SatInstance;
import cz.cvut.fit.mi_paa.sat.Term;

/**
 * Created with IntelliJ IDEA.
 * User: milos
 * Date: 27.1.13
 * Time: 22:02
 * To change this template use File | Settings | File Templates.
 */
public abstract class SatStrategy extends Strategy {
    private SatInstance instance;

    protected SatStrategy(Context context) {
        super(context);
        instance = (SatInstance) context.getInstance();
    }

    protected boolean isNewConfigurationBetter(boolean[] newArray, boolean[] actualArray) {
        int countSatisfiedTermsNewArray=getSatisfiedTermsCount(newArray);
        int countSatisfiedTermsActualArray=getSatisfiedTermsCount(actualArray);
        return countSatisfiedTermsNewArray > countSatisfiedTermsActualArray;
    }

    protected boolean isSolution(boolean[] newArray) {
        boolean result=true;
        for (Term term : instance.getTerms()) {
            result &= term.isSatisfiable(newArray);
            if(!result) break;
        }
        return result;
    }

    protected int getWeightSum(boolean[] array) {
        int weight=0;
        for (int i=0; i<array.length;i++) {
            if(array[i]) weight += instance.getWeights()[i];
        }
        return weight;
    }

    protected int getTermsWeightSum() {
        int weight=0;
        for (Term t : instance.getTerms()) {
            weight += t.getTermWeight(instance.getWeights());
        }
        return weight;
    }

    protected double getAverageWeight() {
        double sum=0;
        for (int i : instance.getWeights()) {
            sum += i;
        }
        return sum/instance.getWeights().length;
    }

    protected double getAverageTermWeight() {
        double sum=0;
        for (Term t : instance.getTerms()) {
            sum += t.getTermWeight(instance.getWeights());
        }
        return sum/instance.getTerms().size();
    }

    protected int getSatisfiedTermsCount(boolean[] array) {
        int countSatisfiedTermsActual=0;
        for (Term term : instance.getTerms()) {
            boolean satisfiableTerm = term.isSatisfiable(array);
            if(satisfiableTerm) countSatisfiedTermsActual++;
        }
        return countSatisfiedTermsActual;
    }


}
